package com.platform.api;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import com.jfinal.aop.Duang;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.wxaapp.api.WxaTemplate;
import com.jfinal.wxaapp.api.WxaTemplateApi;
import com.platform.annotation.IgnoreAuth;
import com.platform.annotation.LoginUser;
import com.platform.config.IntegralType;
import com.platform.entity.*;
import com.platform.service.*;
import com.platform.util.ApiBaseAction;
import com.platform.util.ApiPageUtils;
import com.platform.utils.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.platform.config.Constants.ClassBuySuccess;
import static com.platform.util.CommonUtil.getProp;
import static com.platform.util.wechat.WechatUtil.setWxaConfig;

@RestController
@RequestMapping("/api/warmclass")
public class ApiWarmClassController extends ApiBaseAction {

    @Autowired
    private ApiWarmClassService warmClassService;

    @Autowired
    private ApiWarmClassRecordService recordService;

    @Autowired
    private ApiCollectService collectService;

    @Autowired
    private ApiSysMacroService macroService;

    @Autowired
    private ApiUserIntegralService userIntegralService;

    @Autowired
    private ApiUserService apiUserService;

    static Prop prop = getProp();
    String appid = prop.get("payAppId");
    String partner = prop.get("payMchId");
    String paternerKey = prop.get("payPaternerKey");
    String notify_url = prop.get("payCallBackDomain") + "/api/warmclass/pay_notify";

    /**
     * @param loginUser
     * @param page
     * @param size
     * @param type      类型：1-美文；2-视觉；3-影音；4-收藏
     * @return
     */
    @RequestMapping(value = "list", method = {RequestMethod.GET, RequestMethod.POST})
    public Object getList(@LoginUser UserVo loginUser,
                          @RequestParam(value = "page", defaultValue = "1") Integer page,
                          @RequestParam(value = "size", defaultValue = "10") Integer size,
                          @RequestParam(value = "type", defaultValue = "1") Integer type,
                          @RequestParam(value = "isPay", defaultValue = "0") Integer isPay) {
        Long userId = loginUser.getUserId();
        Map<String, Object> param = new HashMap<>();
        param.put("page", page);
        param.put("limit", size);
        if (type == 1 || type == 2 || type == 3) {
            param.put("type", type);
        } else if (type == 4) {
            param.put("userId", userId);
            param.put("typeId", 1);//收藏类型：0-商品收藏；1-暖课；2-社区故事(帖子)
        } else {
            return toResponsFail("不存在该类型");
        }
        param.put("sidx", "sort_order");//默认按照排序号倒序
        param.put("order", "desc");

        Query query = new Query(param);


        List<WarmClassVo> topicEntities = warmClassService.queryList(query);
        int total = warmClassService.queryTotal(query);

        if (isPay == 1 && type != 4) {
            param.put("userId", userId);
            query = new Query(param);
            topicEntities = warmClassService.queryIsPayList(query);
            total = warmClassService.queryIsPayTotal(query);
        }

        //屏蔽内容
        for (WarmClassVo item : topicEntities) {
            Integer id = item.getId();
            item.setContentDesc("");
            //todo 是否有收藏
            Boolean collected = collectService.isCollected(1, id, userId);
            if (collected) {
                //收藏状态：1-已收藏；0-未收藏
                item.setIsCollected(1);
            }
            //todo 是否有支付(2018-12-11 需求更改为用积分抵扣)
            if (item.getIsFree() == 0) {
//                Boolean pay = recordService.isPay(id, userId);
                Boolean pay = userIntegralService.warmClassIsPay(id, userId);
                if (pay) {
                    //支付状态：1-已支付；0-未支付
                    item.setIsPay(1);
                }
            }
        }

        ApiPageUtils pageUtil = new ApiPageUtils(topicEntities, total, query.getLimit(), query.getPage());

        return toResponsSuccess(pageUtil);
    }


    /**
     * 暖课详情
     *
     * @param loginUser
     * @param id
     * @return
     */
    @RequestMapping(value = "detail", method = {RequestMethod.GET, RequestMethod.POST})
    public Object detail(@LoginUser UserVo loginUser, @RequestParam(value = "id") Integer id) {

        Long userId = loginUser.getUserId();

        WarmClassVo warmClassVo = warmClassService.queryObject(id);
        if (warmClassVo == null) {
            return toResponsFail("不存在该课程");
        }

        //todo 判断用户有无购买该课程
        if (warmClassVo.getIsFree() == 0) {
//            Boolean pay = recordService.isPay(id, userId);
            Boolean pay = userIntegralService.warmClassIsPay(id, userId);
            if (!pay) {
                //todo 返回支付参数(2018-12-11 需求更改为用积分抵扣)
                return toResponsFail("请先用积分兑换");
//                return pay(loginUser, id);
            } else {
                //支付状态：1-已支付；0-未支付
                warmClassVo.setIsPay(1);
            }
        }

        //todo 是否有收藏
        Boolean collected = collectService.isCollected(1, id, userId);
        if (collected) {
            //收藏状态：1-已收藏；0-未收藏
            warmClassVo.setIsCollected(1);
        }

        return toResponsSuccess(warmClassVo);
    }

    /**
     * 暖课支付
     *
     * @param loginUser
     * @param id
     * @return
     */
    @RequestMapping(value = "pay", method = {RequestMethod.GET, RequestMethod.POST})
    public Object pay(@LoginUser UserVo loginUser, @RequestParam(value = "id") Integer id) {
        WarmClassVo warmClassVo = warmClassService.queryObject(id);
        if (warmClassVo == null) {
            return toResponsFail("不存在该课程");
        }
        BigDecimal contentPrice = warmClassVo.getContentPrice();
        Long userId = loginUser.getUserId();


//        //todo 查看购买记录，无需重复购买
//        Map<String, Object> param = new HashMap<>();
//        param.put("userId", loginUser.getUserId());
//        param.put("warmClassId", id);
//        //已支付
//        param.put("isPay", 1);
//        List<WarmClassRecordVo> warmClassRecordVos = recordService.queryList(param);
//        if (warmClassRecordVos.size() > 0) {
//            return toResponsFail("无需重复购买");
//        }
//
//        //todo 创建支付记录
//        WarmClassRecordVo warmClassRecordVo = new WarmClassRecordVo();
//        warmClassRecordVo.setUserId(loginUser.getUserId().intValue());
//        warmClassRecordVo.setUserNickname(loginUser.getNickname());
//        warmClassRecordVo.setWarmClassId(id);
//        warmClassRecordVo.setWarmClassName(warmClassVo.getTitle());
//        warmClassRecordVo.setIsPay(0);
//        warmClassRecordVo.setAddTime(new Date());
//        recordService.save(warmClassRecordVo);
//
//        //todo 微信统一下单
//        String openId = loginUser.getWeixin_openid();
//
//        if (Validator.isEmpty(openId)) {
//            return toResponsFail("请先授权登录");
//        }
//
//        Map<String, String> params = new HashMap<String, String>();
//        params.put("appid", appid);
//        params.put("mch_id", partner);
//        params.put("body", "温暖捐款");
//        String out_trade_no = System.currentTimeMillis() + "";
//        params.put("out_trade_no", out_trade_no);
//        int price = ((int) (contentPrice.floatValue() * 100));
//        params.put("total_fee", price + "");
//        params.put("attach", warmClassRecordVo.getId().toString());
//        String ip = IpKit.getRealIp(request);
//        if (StrKit.isBlank(ip)) {
//            ip = "127.0.0.1";
//        } else {
//            String[] split = ip.split(",");
//            ip = split[0];
//        }
//        params.put("spbill_create_ip", ip);
//        params.put("trade_type", PaymentApi.TradeType.JSAPI.name());
//        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
//        params.put("notify_url", notify_url);
//        params.put("openid", openId);
//        String sign = PaymentKit.createSign(params, paternerKey);
//
//        params.put("sign", sign);
//
//        String xmlResult = PaymentApi.pushOrder(params);
//
//        System.out.println(xmlResult);
//
//        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
//
//        String return_code = result.get("return_code");
//        String return_msg = result.get("return_msg");
//        if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
//            return toResponsFail("支付失败," + "return_code:" + return_msg);
//        }
//        String result_code = result.get("result_code");
//        if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
//            return toResponsFail("支付失败," + "result_code:" + return_msg);
//
//        }
//        // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
//        String prepay_id = result.get("prepay_id");
//
//        logger.info("prepay_id:" + prepay_id);
//
//        //todo 业务处理
//        warmClassRecordVo.setOutTradeNo(out_trade_no);
//        warmClassRecordVo.setPrepayId(prepay_id);
//        recordService.update(warmClassRecordVo);
//
//        Map<String, String> packageParams = new HashMap<>();
//        packageParams.put("appId", appid);
//        packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
//        packageParams.put("nonceStr", System.currentTimeMillis() + "");
//        packageParams.put("package", "prepay_id=" + prepay_id);
//        packageParams.put("signType", "MD5");
//
//        String packageSign = PaymentKit.createSign(packageParams, paternerKey);
//        packageParams.put("paySign", packageSign);


        //todo 查询时候有足够积分兑换
        UserVo userInfo = apiUserService.getUserInfo(userId);
        String integral = userInfo.getIntegral();
        BigDecimal userIntegral = new BigDecimal(integral);
        if (userIntegral.compareTo(contentPrice) < 0) {
            return toResponsFail("积分不足");
        }

        //todo 添加消耗记录
        UserIntegralVo userIntegralVo = new UserIntegralVo();
        userIntegralVo.setUserId(userId.intValue());
        userIntegralVo.setOrderId(id);
        //状态:1-增加；2-减少(即使用)
        userIntegralVo.setStatus(2);
        userIntegralVo.setIntegral(contentPrice.intValue());
        IntegralType orderIntegralType = IntegralType.WARN_CLASS_INTEGRAL_TYPE;
        userIntegralVo.setRemark(orderIntegralType.getName());
        userIntegralVo.setIntegralType(orderIntegralType.getIndex());
        userIntegralVo.setAddTime(new Date());
        userIntegralService.save(userIntegralVo);
        //汇总用户目前积分
        userIntegralService.calUserCurrentPoints(userId, 2, userIntegralVo.getIntegral());
        System.out.println("积分记录成功");

        return toResponsSuccess("支付成功");
    }

    @IgnoreAuth
    @RequestMapping(value = "pay_notify", method = {RequestMethod.GET, RequestMethod.POST})
    public Object pay_notify(HttpServletRequest request, HttpServletResponse response) {

        // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
        String xmlMsg = HttpKit.readData(request);

        System.out.println("支付通知=" + xmlMsg);

        Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);

        // 微信支付订单号
        String transaction_id = params.get("transaction_id");
        String result_code = params.get("result_code");
        String openId = params.get("openid");
        // 商户订单号
        String out_trade_no = params.get("out_trade_no");

        ///////////////////////////// 以下是附加参数///////////////////////////////////

        String recordId = params.get("attach");
        String fee_type = params.get("fee_type");
        String is_subscribe = params.get("is_subscribe");
        String err_code = params.get("err_code");
        String err_code_des = params.get("err_code_des");

        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 避免已经成功、关闭、退款的订单被再次更新
        try {
            if (result_code.equalsIgnoreCase("FAIL")) {
                //订单编号
                logger.error("订单" + out_trade_no + "支付失败");
            } else if (result_code.equalsIgnoreCase("SUCCESS")) {
                //订单编号
                logger.info("订单:" + out_trade_no + "支付成功");
                // 业务处理
                WarmClassRecordVo warmClassRecordVo = recordService.queryObject(Integer.valueOf(recordId));

                if (warmClassRecordVo != null && warmClassRecordVo.getIsPay() == 0) {
                    warmClassRecordVo.setIsPay(1);
                    warmClassRecordVo.setTransactionId(transaction_id);
                    recordService.update(warmClassRecordVo);
                    System.out.println("购买暖课记录更新成功");

                    //todo 课程阅读数加1
                    Integer warmClassId = warmClassRecordVo.getWarmClassId();
                    WarmClassVo warmClassVo = warmClassService.queryObject(warmClassId);
                    warmClassVo.setViewCount(warmClassVo.getViewCount() + 1);
                    warmClassService.update(warmClassVo);
                    System.out.println("课程阅读数更新成功");

                    //发送模板消息
                    setWxaConfig();//小程序配置信息
                    WxaTemplateApi wxaTemplateApi = Duang.duang(WxaTemplateApi.class);
                    WxaTemplate template = new WxaTemplate();
                    template.setForm_id(warmClassRecordVo.getPrepayId());//支付的prepay_id
                    template.setTouser(openId);//接收者（用户）的 openid
                    template.setTemplate_id(ClassBuySuccess);//购买成功通知的模板ID
                    template.setPage("pages/nuankeDetail/nuankeDetail?warmClassId=" + warmClassId);//小程序调转的页面:公益活动详情
                    template.add("keyword1", warmClassVo.getContentPrice().toString());//课程金额
                    template.add("keyword2", warmClassVo.getTitle());//项目名称
                    template.add("keyword3", DateUtil.formatDateTime(warmClassRecordVo.getAddTime()));//购买时间
                    String build = template.build();
                    ApiResult send = wxaTemplateApi.send(build);
                    Integer errorCode = send.getErrorCode();
                    if (errorCode != 0) {
                        System.out.println("模板发送失败信息：" + send.getErrorMsg());
                    }
                    System.out.println("模板信息发送成功");
                }

            }

            Map<String, String> xml = new HashMap<>();
            xml.put("return_code", "SUCCESS");
            xml.put("return_msg", "OK");
            String toXml = PaymentKit.toXml(xml);

            response.reset();
            PrintWriter out = response.getWriter();
            out.write(toXml);
            out.flush();
            out.close();

        } catch (IOException e) {
            logger.error("回调失败");
            e.printStackTrace();
        }

        return toResponsFail("下单失败");

    }

}
